<template>
  <div ref="container"></div>
</template>

<script>
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { Vector2, Raycaster, MeshStandardMaterial } from 'three';
import { mapState } from 'vuex';

export default {
  name: 'CubeComp',
  props: {
    canvasTexture: {
      type: Object,
      default: null
    },
    onInteract: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      width: window.innerWidth,
      height: window.innerHeight,
      cameraPosition: { x: 0, y: 0, z: 6 },
      cameraLookAt: { x: 0, y: 0, z: 0 },
      model: null,
      material: null,
      raycaster: new Raycaster(),
      mouse: new Vector2(),
      isDragging: false,
      modelConfig: {
        jersey: {
          scale: { x: 0.0042, y: 0.0042, z: 0.0042 },
          position: { x: 0, y: 0, z: 0 },
          rotation: { x: 0, y: 0, z: 0 }
        },
        sock: {
          scale: { x: 0.02, y: 0.02, z: 0.02 },
          position: { x: 0, y: -0.5, z: 0 },
          rotation: { x: 0, y: Math.PI / 2, z: 0 }
        }
      }
    };
  },
  computed: {
    ...mapState({
      selectedProductType: state => state.designs.selectedProductType,
      selectedModel: state => {
        const models = state.models.models;
        return models.find(m => m.id === state.models.selectedModelId);
      }
    }),
    currentConfig() {
      return this.modelConfig[this.selectedProductType];
    }
  },
  watch: {
    canvasTexture(newTexture) {
      if (this.material && newTexture) {
        this.material.map = newTexture;
        this.material.needsUpdate = true;
      }
    },
    selectedProductType() {
      this.resetCamera();
    },
    selectedModel: {
      immediate: true,
      handler(newModel) {
        if (newModel) {
          this.loadModel(newModel.path);
        }
      }
    }
  },
  mounted() {
    window.addEventListener('resize', this.onWindowResize);
    this.initMaterial();
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.onWindowResize);
  },
  methods: {
    onRendererMounted({ renderer, scene, camera }) {
      this.renderer = renderer;
      this.scene = scene;
      this.camera = camera;
    },
    initMaterial() {
      this.material = new MeshStandardMaterial({
        color: 'white',
        roughness: 0.9,
        metalness: 0,
        envMapIntensity: 0.2,
        transparent: true,
        side: 2,
        map: this.canvasTexture || null
      });
    },
    async loadModel(path) {
      if (!path) return;

      const loader = new OBJLoader();
      try {
        const model = await new Promise((resolve, reject) => {
          loader.load(
              path,
              resolve,
              null,
              reject
          );
        });

        this.model = model;
        this.setupModel();
      } catch (error) {
        console.error('Error loading model:', error);
      }
    },
    setupModel() {
      if (!this.model || !this.$refs.modelGroup) return;

      // Clear previous model
      const group = this.$refs.modelGroup;
      group.children = [];

      // Clone and add new model
      const modelClone = this.model.clone();
      modelClone.traverse(child => {
        if (child.isMesh) {
          child.material = this.material;
        }
      });

      group.add(modelClone);
    },
    resetCamera() {
      if (this.camera) {
        this.cameraPosition = { x: 0, y: 0, z: 6 };
        this.cameraLookAt = { x: 0, y: 0, z: 0 };
      }
    },
    handlePointerDown(event) {
      event.stopPropagation();

      this.updateMousePosition(event);
      this.raycaster.setFromCamera(this.mouse, this.camera);

      const intersects = this.raycaster.intersectObject(this.$refs.modelGroup, true);

      if (intersects.length > 0 && intersects[0].uv && this.onInteract) {
        const uv = intersects[0].uv.clone();

        this.onInteract({
          x: uv.x,
          y: 1 - uv.y,
          clientX: event.clientX,
          clientY: event.clientY,
          type: 'mousedown'
        });
        this.isDragging = true;
      }
    },
    handlePointerMove(event) {
      if (!this.isDragging || !this.onInteract) return;
      event.stopPropagation();

      this.updateMousePosition(event);
      this.raycaster.setFromCamera(this.mouse, this.camera);

      const intersects = this.raycaster.intersectObject(this.$refs.modelGroup, true);

      if (intersects.length > 0 && intersects[0].uv) {
        const uv = intersects[0].uv;
        this.onInteract({
          x: uv.x,
          y: 1 - uv.y,
          clientX: event.clientX,
          clientY: event.clientY,
          type: 'mousemove'
        });
      }
    },
    handlePointerUp(event) {
      if (!this.isDragging || !this.onInteract) return;
      event.stopPropagation();

      this.updateMousePosition(event);
      this.raycaster.setFromCamera(this.mouse, this.camera);

      const intersects = this.raycaster.intersectObject(this.$refs.modelGroup, true);

      if (intersects.length > 0 && intersects[0].uv) {
        const uv = intersects[0].uv;
        this.onInteract({
          x: uv.x,
          y: 1 - uv.y,
          clientX: event.clientX,
          clientY: event.clientY,
          type: 'mouseup'
        });
      }
      this.isDragging = false;
    },
    updateMousePosition(event) {
      const rect = this.$refs.renderer.domElement.getBoundingClientRect();
      this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
    },
    onWindowResize() {
      this.width = window.innerWidth;
      this.height = window.innerHeight;
    }
  }
};
</script>